<?php
/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Kernel
 */
namespace Albireo\OAuth;

use Nette\Object;

use Albireo\FileSystem\UrlBuilder;

use \OAuth;
use \OAuthException;

/**
 * OAuthRequestHandler. Currently tailored for Google API / albireo.eu consumer.
 * 
 * TODO: Shall be refactorized (for us to be able to use it for our apps too).
 *
 * @author pavel
 */

class AuthClient extends Object {
    
    const consumerKey = "albireo.eu";
    const consumerSecret = "Sj+TputrEBdJUbLgJdDNpPBi";
    
    const urlRequestToken = "https://www.google.com/accounts/OAuthGetRequestToken";
    const urlAuthorizeToken = "https://www.google.com/accounts/OAuthAuthorizeToken";
    const urlAccessToken = "https://www.google.com/accounts/OAuthGetAccessToken";
    
    private $oAuth;
    
    public function __construct() {
        $this->oAuth = new OAuth(self::consumerKey, self::consumerSecret);
    }
    
    /**
     * Gets the OAuth Request Token from google server.
     * 
     * @param String $callbackUrl The URL we want to get redirected after OAuthorization
     * @param mixed $scope String or array(String) representing the scope we want
     *        to access. It's google specific parameter.
     * @return array(String => String/bool) The array of succesfuly recieved request
     *          token from google with its additional data. It looks just like this:
     *              array(
     *                  "oauth_token" => "4/K7mLjree3Kf3nxmg3VDbJ_8FVCJ7"
     *                  "oauth_token_secret" => "P3IXvLecZtwoLkqPejaUOmu9"
     *                  "oauth_callback_confirmed" => "true"
     *              );
     * 
     * @throws OAuthException when something screws up
     */
    public function getRequestToken($callbackUrl, $scope = array()) {
        if ($callbackUrl === null) {
            throw new \Exception("Null callback URL");
            //$callbackUrl = "http" . ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
        }
        
        $urlBuilder = new UrlBuilder(self::urlRequestToken);
        if (\is_array($scope)) {
            $scope = $urlBuilder->separateByWhitespaces($scope);
        }
        $urlBuilder->addParameter("scope", $scope);
        $url = $urlBuilder->build();
        
        try {
            return $this->oAuth->getRequestToken($url, $callbackUrl);
        } catch (OAuthException $e) {
            throw $e;
        }
        
    }
    
    /**
     * Returns the URL user should be redirected to grant authorization.
     * 
     * @param array $requestTokenInfo 
     */
    public function authorizationUrl(array $requestTokenInfo) {
        $urlBuilder = new UrlBuilder(self::urlAuthorizeToken);
        $urlBuilder->addParameter("oauth_token", $requestTokenInfo["oauth_token"]);
        return $urlBuilder->build();
    }
    
    public function getAccessToken($authToken, $tokenSecret) {
        $this->oAuth->setToken($authToken, $tokenSecret);
        try {
            $result = $this->oAuth->getAccessToken(self::urlAccessToken);
            return $result;
        } catch (OAuthException $e) {
            //echo $e->lastResponse;
            throw $e;
        }
    }
    
    public function fetch($accessToken, $accessTokenSecret, $url) {
        $this->oAuth->setToken($accessToken, $accessTokenSecret);
        try {
            $result = $this->oAuth->fetch($url, null, OAUTH_HTTP_METHOD_GET, array('GData-Version'=>'3.0'));
            \Nette\Debug::dump($this->oAuth->getLastResponseInfo());
            return $this->oAuth->getLastResponse();
        } catch (OAuthException $e) {
            echo $e->lastResponse;
            //throw $e;
        }
    }        
}